package com.servlet;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.easywan.utils.Config;

import net.coobird.thumbnailator.Thumbnails;


public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static Logger logger = Logger.getLogger(UploadServlet.class.getName());
    
    // 定义允许上传的文件扩展名
    private String Ext_Name = "gif,jpg,jpeg,png,bmp,swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2";

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    	response.setCharacterEncoding("UTF-8");
    	response.setContentType("text/html;charset=utf-8");
    	//1.应该返回一个默认的图片地址
        String resultString = "62da04bf51463997ae144be2802a49_11.png";
        //初始化所有文件路径
        String savePath = Config.get("imgPath");
        File saveFileDir = new File(savePath);
        if (!saveFileDir.exists()) {
            // 创建临时目录
            saveFileDir.mkdirs();
        }
        File destFileDir = new File(Config.get("imgDestPath"));
        if(!destFileDir.exists()){
        	 saveFileDir.mkdirs();
        }
        // 上传时生成临时文件保存目录
        String tmpPath = Config.get("imgTempPath");
        File tmpFile = new File(tmpPath);
        if (!tmpFile.exists()) {
            // 创建临时目录
            tmpFile.mkdirs();
        }
        try {
            
    	  if (!ServletFileUpload.isMultipartContent(request)) {return ;}
        	ServletFileUpload upload = init(tmpFile);
            List<FileItem> items = upload.parseRequest(request);
            Iterator<FileItem> itr = items.iterator();
            Map<String,Object> p = new HashMap<String,Object>();
            while (itr.hasNext()) {
            	 FileItem item = (FileItem) itr.next();
            	 if (item.isFormField()) {//获取普通参数
            		// 如果fileitem中封装的是普通的输入想数据
                     String name = item.getFieldName();
                     // 解决普通输入项数据中文乱码问题
                     String value = item.getString("UTF-8");
                     value = new String(value.getBytes("iso8859-1"),"UTF-8");
                     logger.info(name+":"+value);
                     p.put(name, value);
            	 }else{
            		 String fileName = item.getName();
            		// 得到上传文件的文件名
                     if (fileName == null && fileName.trim().length() == 0) {
                         continue;
                     }
                     // 注意：不同的浏览器提交的文件名是不一样的，有些浏览器提交上来的文件名是带有路径的
                     // 如: C:\Users\H__D\Desktop\1.txt 而有些则是 ： 1.txt
                     // 处理获取到的上传文件的文件名的路径部分，只保留文件名部分
                     fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
                     // 得到上传文件的扩展名
                     String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                     if(!Ext_Name.contains(fileExt)){
                    	 response.getWriter().write("上传文件非法");
                         return;
                     }
                     System.out.println(item.getFieldName());
                    p.put(item.getFieldName(), item);
                    p.put(item.getFieldName()+"fileName", fileName);
            	 }
            }
            
            //获取想要的参数
            String dest = (String) p.get("dest");
            String wString = (String) p.get("w");
            String name = (String)p.get("username");
            FileItem file = (FileItem) p.get("file1");
            String fileName = (String) p.get("file1fileName");
            //保存文件
            String saveFileName = makeFileName(fileName);
            //创建一个文件输出流
            resultString = saveFileName;
            //保存文件方法一// 获取item中的上传文件的输入流
            InputStream is = file.getInputStream();
            FileOutputStream out = new FileOutputStream(savePath  + saveFileName);
            //创建一个缓冲区
            byte buffer[] = new byte[1024];
            //判断输入流中的数据是否已经读完的标致
            int len = 0;
            while((len = is.read(buffer)) > 0){
                out.write(buffer, 0, len);
            }
          
            //关闭输出流
            out.close();
            //关闭输入流
            is.close();
            //删除临时文件
            file.delete();
            if("dest".equals(dest)){
            	BufferedImage img =  ImageIO.read(new File(savePath  + saveFileName));
            	int width = Integer.valueOf(wString);
            	float s = width* 1.0f/img.getWidth();
            	logger.info(Config.get("imgDestPath")+saveFileName);
            	File f = new File(Config.get("imgDestPath")+saveFileName);
            	Thumbnails.of(savePath  + saveFileName).scale(s).toFile(f);
            }
                    } catch (FileSizeLimitExceededException e) {
            e.printStackTrace();
            response.getWriter().write(e.getMessage());;
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write(e.getMessage());;
        } 
        request.setAttribute("result", resultString);
    	request.getRequestDispatcher("/upload.jsp").forward(request, response);

    }
    

    
    private String makeFileName(String fileName) {
        // 为防止文件覆盖的现象发生，要为上传文件产生一个唯一的文件名
        return UUID.randomUUID().toString().replaceAll("-", "") + "_" + fileName;
        
    }
    @Override
    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException ,IOException {
    	System.out.println("doOptions");
    	resp.setHeader("Access-Control-Allow-Origin", "*");
    	resp.setHeader("Access-Control-Allow-Methods", "POST, PUT, OPTIONS");
    	String method = req.getMethod();
         if ("OPTIONS".equals(method)) {
             return;
        }
    }
    protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	super.doHead(req, resp);
    }
    public ServletFileUpload init(File tmpFile){
    	// 使用Apache文件上传组件处理文件上传步骤：
        // 1.创建一个DiskFileItemFactory工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 设置工厂的缓冲区的大小，当上传的文件大小超过缓冲区的大小时，就会生成一个临时文件存放到指定的临时目录当中
        factory.setSizeThreshold(1024 * 10);// 设置缓冲区的大小为100KB，如果不指定，那么默认缓冲区的大小是10KB
        // 设置上传时生成的临时文件的保存目录
        factory.setRepository(tmpFile);
        // 2.创建一个文件上传解析器
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 监听文件上传进度
       /* upload.setProgressListener(new ProgressListener() {
            public void update(long readedBytes, long totalBytes, int currentItem) {
            }
        });*/
        // 解决上传文件名的中文乱码问题
        upload.setHeaderEncoding("UTF-8");
        // 3.判断提交上来的数据是否是上传表单的数据
      

        // 设置上传单个文件的最大值
        upload.setFileSizeMax(1024 * 1024 * 10);// 10M
        // 设置上传文件总量的最大值，就是本次上传的所有文件的总和的最大值
        upload.setSizeMax(1024 * 1024 * 100);// 100M
        return upload;
    }
}